package com.kilomob.grady.handler.netty;

import io.netty.channel.Channel;

import java.util.Map;
import java.util.concurrent.Callable;

import org.apache.commons.lang3.reflect.MethodUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.kilomob.grady.model.Request;
import com.kilomob.grady.model.Response;

/**
 * 
 * 业务处理代理类
 *   
 * @author zhouzhixiang  
 * @date 2017年1月2日
 * @since 1.0
 */
public class MessageReceiveInitializeTask implements Callable<Boolean> {
    private static final Logger LOGGER = LoggerFactory.getLogger(MessageReceiveInitializeTask.class);
    private Request request = null;
    private Response response = null;
    private Map<String, Object> handlerMap = null;
    private Channel channel;

    public Response getResponse() {
        return response;
    }

    public Request getRequest() {
        return request;
    }

    public void setRequest(Request request) {
        this.request = request;
    }

    MessageReceiveInitializeTask(Channel channel,Request request, Response response,
            Map<String, Object> handlerMap) {
        this.channel = channel;
        this.request = request;
        this.response = response;
        this.handlerMap = handlerMap;
    }

    public Boolean call() {
        response.setMessageId(request.getMessageId());
        try {
            Object result = reflect(request);
            response.setResult(result);
            channel.writeAndFlush(response);
            return Boolean.TRUE;
        } catch (Throwable t) {
            LOGGER.error("hanler this request error:",t);
            response.setError(t.toString());
            channel.writeAndFlush(response);
            return Boolean.FALSE;
        }
    }

    private Object reflect(Request request) throws Throwable {
        String className = request.getClassName();
        Object serviceBean = handlerMap.get(className);
        String methodName = request.getMethodName();
        Object[] parameters = request.getParameters();
        return MethodUtils.invokeMethod(serviceBean, methodName, parameters);
    }
}
